import com.google.common.collect.ImmutableList;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ClientConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.zk.TcpDiscoveryZookeeperIpFinder;

import javax.cache.configuration.Factory;
import javax.cache.configuration.FactoryBuilder;
import java.util.ArrayList;
import java.util.List;

/**
 * Baihejia
 * Created by wangguodong on 12/01/2018.
 */
public class Server {

    private static List<Class> entityClassSet = DB.getTables();

    private static IgniteConfiguration getIgniteConfiguration() throws NoSuchFieldException {
        System.setProperty("IGNITE_REST_START_ON_CLIENT", "true");
        System.setProperty("IGNITE_QUIET", "false");
        System.setProperty("PROP_TX_ALLOWED", "true");

        IgniteConfiguration c = new IgniteConfiguration().setClientConnectorConfiguration(new ClientConnectorConfiguration());;
        c.setPeerClassLoadingEnabled(true);
        c.setCacheConfiguration(getCacheConfiguration(entityClassSet));

        TcpDiscoverySpi spi = new TcpDiscoverySpi();
        TcpDiscoveryZookeeperIpFinder ipFinder = new TcpDiscoveryZookeeperIpFinder();
        ipFinder.setZkConnectionString("10.141.142.227:2181");
        spi.setIpFinder(ipFinder);
        c.setDiscoverySpi(spi);

        return c;
    }

    public static void main(String[] args) throws NoSuchFieldException {
        Ignite ignite = Ignition.start(getIgniteConfiguration());
        for (Class entityClass : entityClassSet) {
            IgniteCache igniteCache = ignite.getOrCreateCache(new CacheConfiguration<>(entityClass.getSimpleName())
                    .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
            igniteCache.loadCache(null);
            long maxId = (long)((List)igniteCache.query(new SqlFieldsQuery(String.format("select max(id) from %s.%s", "base", entityClass.getSimpleName()))).iterator().next()).get(0);
            ignite.atomicSequence(entityClass.getSimpleName(), maxId, true);
        }
    }

    public static CacheConfiguration[] getCacheConfiguration(List<Class> clsList) throws NoSuchFieldException {

        List<CacheConfiguration> list = new ArrayList<>();

        for (Class cls : clsList) {
            CacheConfiguration<Long, DBCacheStore> cacheConfiguration = new CacheConfiguration<>();
            cacheConfiguration.setBackups(1);
            cacheConfiguration.setSqlSchema("base");
            cacheConfiguration.setName(cls.getSimpleName());
            cacheConfiguration.setReadThrough(true);
            cacheConfiguration.setWriteThrough(true);
            Factory factory = FactoryBuilder.factoryOf(new DBCacheStore<>(cls));
            cacheConfiguration.setCacheStoreFactory(factory);
            cacheConfiguration.setQueryEntities(ImmutableList.of(new QueryEntity(cls.getField("id").getType(), cls)));

            list.add(cacheConfiguration);
        }

        return list.toArray(new CacheConfiguration[list.size()]);
    }
}
